<?php

class XMLRPCAction extends ControllerAction {
	
	public function __construct(HTTPRequest $request,
		                        Dispatcher $dispatcher,
		                        Resolver $resolver,
		                        array $specification,
		                        array $options) {
		
		$this->options = $options;
		$arguments = xmlrpc_decode_request($request->body(), $this->action_name);
		
		
		parent::__construct($request, $dispatcher, $resolver, '', $arguments, $specification);
	}
	
	protected function initialize($specification, $arguments) {
		$this->dispatch_map = $this->options['dispatch_map'];	
		$this->arguments = $arguments;
	}
	
	
	protected function loadAction() {

		list($namespace, $this->action_name) = explode('.', $this->action_name);
		if (isset($this->dispatch_map[$namespace])) {
			list($this->application_name, $this->controller_name) = 
				explode('.', $this->dispatch_map[$namespace]);
			$this->action_label = $this->dispatch_map[$namespace] . '.' . $this->action_name;
		}

		parent::loadAction();
		
		
	}
	
	public function dispatchMap() {
		return $this->dispatch_map;
	}
	
	protected function processResponse($response) {
		
		$annotation = new SignatureAnnotation($this->reflection());
		$response_type = gettype($response);
		$possible_response_types = $annotation->returnTypes();
		
		if ($response_type == 'object') {
			if ($response instanceof DateTime) {
				$response = $response->format(DATE_ISO8601);
				xmlrpc_set_type($response, 'datetime');
			} else
				$response = get_object_vars($response);
			
		} else if ($response_type == 'string') {
			$xml_rpc_type = isset($possible_response_types[0]) ? 
				$possible_response_types[0] :
				'string';
			
			xmlrpc_set_type($response, $xml_rpc_type);
		}

		$xml = xmlrpc_encode_request(NULL, $response, array('encoding' => 'utf-8'));		

		return new HTTPResponse($xml, HTTPResponse::OK, MIMEType::XML);
	}
	
	
	public static function dispatch(array $dispatch_map) {
		return new GenericActionFactory('XMLRPCAction', array('dispatch_map' => $dispatch_map));
	}
}